Middleware FastAPI অ্যাপ্লিকেশনে রিকোয়েস্ট এবং রেসপন্সের উপর প্রি-প্রসেসিং বা পোস্ট-প্রসেসিং করার জন্য ব্যবহৃত হয়। এটি সাধারণত লগিং, সিকিউরিটি চেক, সেশন ব্যবস্থাপনা, CORS (Cross-Origin Resource Sharing) হ্যান্ডলিং ইত্যাদির জন্য ব্যবহৃত হয়।
FastAPI তে middleware তৈরি এবং কনফিগার করা খুবই সহজ। এখানে আমরা দেখব কীভাবে আপনি FastAPI-তে Middleware ব্যবহার করতে পারেন এবং Custom Middleware তৈরি করতে পারেন।
Middleware ব্যবহারের মৌলিক ধারণা
FastAPI তে Middleware একটি ক্লাস হিসেবে তৈরি করা হয়, যা BaseHTTPMiddleware থেকে ইনহেরিট করে। এই ক্লাসটি অ্যাপ্লিকেশন এ থাকা প্রতিটি রিকোয়েস্ট এবং রেসপন্সের উপর কাজ করতে সক্ষম।
FastAPI তে Middleware কিভাবে কাজ করে:
- Request Handling: রিকোয়েস্ট পাওয়ার আগে middleware কাজ করে।
- Response Handling: রেসপন্স ক্লায়েন্টে পাঠানোর আগে middleware কাজ করে।
FastAPI তে Middleware ব্যবহার করতে, আমরা add_middleware মেথড ব্যবহার করি।
FastAPI তে Built-in Middleware
FastAPI তে কিছু Built-in Middleware আছে, যেমন:
- CORSMiddleware: CORS পলিসি পরিচালনা করার জন্য।
- GZipMiddleware: রেসপন্স কম্প্রেস করার জন্য।
- TrustedHostMiddleware: অ্যাপ্লিকেশনকে নির্দিষ্ট হোস্ট নাম বা আইপি অ্যাড্রেসের উপর সুরক্ষিত রাখতে ব্যবহৃত হয়।
উদাহরণ: CORS Middleware
from fastapi import FastAPI
from starlette.middleware.cors import CORSMiddleware
app = FastAPI()
# CORS Middleware যোগ করা
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # সকল ডোমেইনকে অনুমতি দিন
allow_credentials=True,
allow_methods=["*"], # সকল HTTP মেথড অনুমতি দিন
allow_headers=["*"], # সকল হেডার অনুমতি দিন
)
@app.get("/")
def read_root():
return {"message": "Hello, World!"}
এখানে, CORS Middleware যোগ করা হয়েছে যা সকল হোস্ট এবং মেথডের জন্য অনুমতি দেয়।
Custom Middleware তৈরি করা
FastAPI তে Custom Middleware তৈরি করার জন্য BaseHTTPMiddleware ব্যবহার করা হয়। এটি ক্লাসের মাধ্যমে কাস্টম প্রি-প্রসেসিং এবং পোস্ট-প্রসেসিং কাজ পরিচালনা করতে সক্ষম।
উদাহরণ: Custom Logging Middleware
from fastapi import FastAPI
from starlette.middleware.base import BaseHTTPMiddleware
import time
app = FastAPI()
# Custom Middleware তৈরি
class LoggingMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request, call_next):
start_time = time.time()
response = await call_next(request)
process_time = time.time() - start_time
print(f"Request took {process_time:.4f} seconds")
return response
# Middleware অ্যাপ্লিকেশনে যোগ করা
app.add_middleware(LoggingMiddleware)
@app.get("/")
def read_root():
return {"message": "Hello, World!"}
এখানে, LoggingMiddleware একটি কাস্টম middleware যা রিকোয়েস্ট প্রক্রিয়া করতে সময় পরিমাপ করে এবং তা কনসোলে প্রিন্ট করে।
রেসপন্স:
Request took 0.0001 seconds
Custom Middleware: Request এবং Response হ্যান্ডলিং
Middleware তে Request এবং Response উভয়ই হ্যান্ডল করা যায়। আপনি রিকোয়েস্টের হেডার চেক, কুকি পরিচালনা, বা রেসপন্সে ম্যানিপুলেশনও করতে পারেন।
উদাহরণ: Custom Middleware (Request Header Checking)
from fastapi import FastAPI
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.responses import JSONResponse
app = FastAPI()
# Custom Middleware - Request Header Checking
class HeaderCheckingMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request, call_next):
user_agent = request.headers.get("user-agent")
if not user_agent:
return JSONResponse(
content={"message": "User-Agent header missing"},
status_code=400,
)
response = await call_next(request)
return response
# Middleware অ্যাপ্লিকেশনে যোগ করা
app.add_middleware(HeaderCheckingMiddleware)
@app.get("/")
def read_root():
return {"message": "Hello, World!"}
এখানে, HeaderCheckingMiddleware ক্লাসটি user-agent হেডার চেক করে এবং এটি না থাকলে 400 (Bad Request) রেসপন্স ফেরত দেয়।
রেসপন্স (যদি user-agent হেডার না থাকে):
{
"message": "User-Agent header missing"
}
Middleware ব্যবহার করার কিছু গুরুত্বপূর্ণ পয়েন্ট
- Pre-processing: Middleware রিকোয়েস্ট গ্রহণের আগে কাজ করতে পারে, যেমন অ্যাডমিন অথেনটিকেশন চেক করা।
- Post-processing: Middleware রেসপন্স পাঠানোর আগে কাজ করতে পারে, যেমন লগিং, রেসপন্স কাস্টমাইজেশন।
- Error Handling: Middleware রিকোয়েস্ট বা রেসপন্সের সময় ত্রুটি হ্যান্ডলিং করতে সাহায্য করতে পারে, যেমন কাস্টম ত্রুটি বার্তা তৈরি করা।
FastAPI তে Multiple Middleware ব্যবহারের উদাহরণ
FastAPI-তে আপনি একাধিক middleware একসাথে ব্যবহার করতে পারেন। একাধিক middleware যোগ করতে, add_middleware বারবার ব্যবহার করুন।
from fastapi import FastAPI
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.middleware.cors import CORSMiddleware
import time
app = FastAPI()
# Logging Middleware
class LoggingMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request, call_next):
start_time = time.time()
response = await call_next(request)
process_time = time.time() - start_time
print(f"Request took {process_time:.4f} seconds")
return response
# Adding multiple middleware
app.add_middleware(LoggingMiddleware)
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # Allow all origins
allow_credentials=True,
allow_methods=["*"], # Allow all HTTP methods
allow_headers=["*"], # Allow all headers
)
@app.get("/")
def read_root():
return {"message": "Hello, World!"}
এখানে, আমরা দুটি middleware ব্যবহার করেছি:
- LoggingMiddleware: রিকোয়েস্ট প্রক্রিয়া সময় লগ করবে।
- CORSMiddleware: CORS পলিসি ম্যানেজ করবে।
FastAPI তে Middleware ব্যবহারের মাধ্যমে আপনি রিকোয়েস্ট এবং রেসপন্সের উপর প্রি-প্রসেসিং বা পোস্ট-প্রসেসিং করতে পারেন। Custom Middleware তৈরি করার মাধ্যমে আপনি API-র আচরণ কাস্টমাইজ করতে পারেন, যেমন লগিং, সিকিউরিটি, CORS পলিসি, বা রিকোয়েস্ট হেডার যাচাই। FastAPI middleware ব্যবহারের ফলে অ্যাপ্লিকেশনের কার্যক্ষমতা এবং নিরাপত্তা বাড়ানো যায়।
Middleware হল একটি প্রক্রিয়া যা রিকোয়েস্ট এবং রেসপন্সের মধ্যে প্রক্রিয়া চলে। এটি সাধারণত রিকোয়েস্ট প্রাপ্ত হওয়ার আগে বা রেসপন্স ফেরত দেওয়ার আগে একাধিক কাজ সম্পাদন করতে ব্যবহৃত হয়। FastAPI-তে, Middleware HTTP রিকোয়েস্টের জন্য একটি স্তর হিসাবে কাজ করে, এবং এটি সার্ভারের কাজের মধ্যে অতিরিক্ত কার্যকলাপ যুক্ত করতে ব্যবহার করা হয়।
Middleware ব্যবহার করে আপনি রিকোয়েস্ট বা রেসপন্স প্রসেসিংয়ে পরিবর্তন আনতে পারেন, যেমন লগিং, অথেনটিকেশন, সিকিউরিটি চেকিং, এবং রিকোয়েস্টের জন্য সেন্ট্রালাইজড হ্যান্ডলিং।
FastAPI-তে Middleware কীভাবে কাজ করে?
FastAPI-তে Middleware একটি ক্লাস বা ফাংশন যা প্রতিটি রিকোয়েস্টের আগে এবং পরে কার্যকর হয়। আপনি Middleware এর মাধ্যমে রিকোয়েস্ট প্রসেস করতে পারেন এবং রেসপন্স তৈরি করার আগেই কোন অতিরিক্ত কাজ সম্পাদন করতে পারেন।
FastAPI-তে Middleware সাধারণত BaseHTTPMiddleware ব্যবহার করে তৈরি করা হয়। এটি starlette.middleware.base থেকে আসে, যেটি FastAPI এর অ্যাপ্লিকেশন স্ট্যাকের উপর ভিত্তি করে কাজ করে।
Middleware এর প্রয়োজনীয়তা কেন?
১. রিকোয়েস্ট লজিক কেন্দ্রীকরণ:
Middleware ব্যবহার করে আপনি বারবার ব্যবহৃত কোড এক জায়গায় কেন্দ্রীভূত করতে পারেন। যেমন, একাধিক এন্ডপয়েন্টের জন্য লগিং বা অথেনটিকেশন চেকিং করতে, আপনি একটি সাধারণ Middleware ব্যবহার করতে পারেন।
২. অথেনটিকেশন এবং অথোরাইজেশন:
Middleware ব্যবহার করে আপনি ব্যবহারকারীর অথেনটিকেশন বা অথোরাইজেশন চেক করতে পারেন। এতে করে একই কোড বারবার এন্ডপয়েন্টে ব্যবহার না করে একযোগভাবে সার্ভারের স্তরে সুরক্ষা নিশ্চিত করা হয়।
৩. লগিং এবং মনিটরিং:
Middleware ব্যবহার করে সমস্ত রিকোয়েস্ট এবং রেসপন্সের জন্য লগ রাখা যায়, যা সিস্টেম মনিটরিং এবং ত্রুটি সনাক্তকরণে সহায়ক হতে পারে।
৪. রিকোয়েস্ট এবং রেসপন্স পরিবর্তন:
কিছু Middleware রিকোয়েস্ট বা রেসপন্সে পরিবর্তন করতে পারে। যেমন, হেডার যোগ করা, রিকোয়েস্ট প্যারামিটার বদলানো, রেসপন্স কন্টেন্ট প্রসেস করা ইত্যাদি।
৫. কাস্টম সিকিউরিটি চেক:
আপনার API বা অ্যাপ্লিকেশনে কাস্টম সিকিউরিটি চেক করার জন্য Middleware ব্যবহার করা যেতে পারে। যেমন, API কিওর চেক, ডোজ (DoS) আক্রমণ প্রতিরোধ ইত্যাদি।
FastAPI-তে Middleware কিভাবে কাজ করে?
FastAPI তে Middleware তৈরি করার জন্য BaseHTTPMiddleware ক্লাসটি ব্যবহার করা হয়। এখানে একটি সাধারণ উদাহরণ দেওয়া হলো:
উদাহরণ: Basic Middleware in FastAPI
from fastapi import FastAPI
from starlette.middleware.base import BaseHTTPMiddleware
class CustomMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request, call_next):
# রিকোয়েস্ট আসার আগে কাজ
print(f"Request URL: {request.url}")
# রিকোয়েস্ট প্রসেস করা হচ্ছে
response = await call_next(request)
# রেসপন্স আসার পরে কাজ
response.headers['X-Custom-Header'] = 'Hello from Middleware'
return response
app = FastAPI()
# Middleware যুক্ত করা
app.add_middleware(CustomMiddleware)
@app.get("/")
async def read_root():
return {"message": "Hello, FastAPI!"}
এখানে:
dispatchমেথডটি রিকোয়েস্ট আসার আগে এবং রেসপন্স তৈরি হওয়ার পরে কার্যকর হয়।call_nextহল একটি ফাংশন যা পরবর্তী রিকোয়েস্ট প্রসেসিং করে এবং রেসপন্স ফিরিয়ে আনে।response.headersব্যবহার করে কাস্টম হেডার যোগ করা হয়েছে।
রেসপন্স:
যখন আপনি / এন্ডপয়েন্টে রিকোয়েস্ট করবেন, তখন রেসপন্সে X-Custom-Header হেডার সহ ফিরবে।
{
"message": "Hello, FastAPI!"
}
এবং রেসপন্স হেডার:
X-Custom-Header: Hello from Middleware
FastAPI-তে বিভিন্ন Middleware ব্যবহার
FastAPI-তে আপনি বিভিন্ন কাজের জন্য বহু ধরনের Middleware ব্যবহার করতে পারেন। কিছু উদাহরণ:
১. CORS (Cross-Origin Resource Sharing) Middleware:
CORS সেটআপ করার জন্য FastAPI-তে CORSMiddleware ব্যবহার করা হয়, যা আপনার API কে অন্যান্য ডোমেইন থেকে রিকোয়েস্ট প্রক্রিয়া করতে দেয়।
from fastapi import FastAPI
from starlette.middleware.cors import CORSMiddleware
app = FastAPI()
# CORS Middleware যুক্ত করা
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # সকল উৎস থেকে রিকোয়েস্ট অনুমোদন
allow_credentials=True,
allow_methods=["*"], # সকল HTTP মেথড অনুমোদন
allow_headers=["*"], # সকল হেডার অনুমোদন
)
@app.get("/")
async def read_root():
return {"message": "Hello, FastAPI with CORS!"}
২. Session Middleware:
আপনি যদি ক্লায়েন্টের সাথে সেশন সংরক্ষণ করতে চান, তবে SessionMiddleware ব্যবহার করতে পারেন।
from starlette.middleware.sessions import SessionMiddleware
app.add_middleware(SessionMiddleware, secret_key="mysecret")
FastAPI Middleware কাস্টমাইজেশন
FastAPI-তে Middleware কাস্টমাইজ করা যায় যেখানে আপনি রিকোয়েস্ট এবং রেসপন্স উভয়ের উপর নিয়ন্ত্রণ রাখতে পারেন। আপনি সহজেই রিকোয়েস্টের হেডার, কুকি, এবং রেসপন্সের কন্টেন্ট পরিবর্তন করতে পারেন।
উদাহরণ: Request এবং Response কাস্টমাইজেশন
from fastapi import FastAPI
from starlette.middleware.base import BaseHTTPMiddleware
class CustomMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request, call_next):
# রিকোয়েস্ট হেডার পরিবর্তন
request.headers['X-Custom-Request-Header'] = 'Custom Header Value'
# রেসপন্স তৈরির পরে হেডার পরিবর্তন
response = await call_next(request)
response.headers['X-Custom-Response-Header'] = 'Response Header Value'
return response
app = FastAPI()
# কাস্টম Middleware যুক্ত করা
app.add_middleware(CustomMiddleware)
@app.get("/")
async def read_root():
return {"message": "Custom middleware is working!"}
Middleware FastAPI-তে একটি অত্যন্ত গুরুত্বপূর্ণ অংশ, যা রিকোয়েস্ট এবং রেসপন্সের উপর নিয়ন্ত্রণ দেয়। এটি বিভিন্ন কার্যকলাপের জন্য যেমন লগিং, অথেনটিকেশন, সিকিউরিটি, এবং অন্যান্য সাধারণ ফিচার হ্যান্ডল করতে ব্যবহৃত হয়। Middleware ব্যবহার করে আপনি অ্যাপ্লিকেশনের কার্যকারিতা সহজেই কাস্টমাইজ এবং প্রসারিত করতে পারেন।
FastAPI তে বিল্ট-ইন Middleware ব্যবহার করা হয় যেটি বিভিন্ন সাধারণ কাজ যেমন CORS (Cross-Origin Resource Sharing), সেশন ম্যানেজমেন্ট, এবং অন্যান্য সাধারণ ফিচার হ্যান্ডলিংয়ের জন্য সহায়ক। FastAPI তে কিছু প্রি-বuilt Middleware রয়েছে যেগুলি সহজে কনফিগার করা যায় এবং ব্যবহার করা যায়।
এখানে FastAPI এর বিল্ট-ইন Middleware এর কিছু সাধারণ ব্যবহার দেখানো হবে:
১. CORSMiddleware
CORS (Cross-Origin Resource Sharing) হল একটি নিরাপত্তা বৈশিষ্ট্য যা এক ডোমেইন থেকে অন্য ডোমেইনে রিকোয়েস্টের অনুমতি দেয়। যখন আপনি API তৈরি করেন, এটি বিশেষত গুরুত্বপূর্ণ হয় যাতে আপনার API অন্য ডোমেইন থেকে রিকোয়েস্ট গ্রহণ করতে পারে।
উদাহরণ: CORS Middleware ব্যবহার করা
FastAPI তে CORSMiddleware ব্যবহার করে সহজে CORS কনফিগার করা যায়।
from fastapi import FastAPI
from starlette.middleware.cors import CORSMiddleware
app = FastAPI()
# CORS Middleware যুক্ত করা
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # কোন ডোমেইন থেকে রিকোয়েস্ট আসতে পারে
allow_credentials=True,
allow_methods=["*"], # সকল HTTP মেথডে রিকোয়েস্ট অনুমতি
allow_headers=["*"], # সকল হেডারে রিকোয়েস্ট অনুমতি
)
@app.get("/")
async def read_root():
return {"message": "Hello, FastAPI with CORS!"}
এখানে:
allow_origins=["*"]: সকল উৎস (domains) থেকে রিকোয়েস্ট গ্রহণের অনুমতি দেয়।allow_methods=["*"]: সকল HTTP মেথড (GET, POST, PUT, DELETE ইত্যাদি) অনুমতি দেয়।allow_headers=["*"]: সকল হেডারের মাধ্যমে রিকোয়েস্ট পাঠানোর অনুমতি দেয়।
রিকোয়েস্ট উদাহরণ:
আপনি যদি আপনার API কে অন্য ডোমেইন থেকে কল করতে চান, তাহলে এটি CORS কনফিগারেশন দ্বারা অনুমোদিত হবে।
২. SessionMiddleware
FastAPI তে SessionMiddleware ব্যবহার করা হয় যদি আপনি ক্লায়েন্ট সেশন ম্যানেজমেন্ট করতে চান। এটি HTTP সেশনের মাধ্যমে স্টেটফুল সেশন ম্যানেজমেন্ট প্রদান করে, যেখানে ব্যবহারকারীর ডেটা সেশন কুকির মাধ্যমে সংরক্ষণ করা হয়।
উদাহরণ: SessionMiddleware ব্যবহার করা
from fastapi import FastAPI
from starlette.middleware.sessions import SessionMiddleware
app = FastAPI()
# সেশন কুকি সেট করা
app.add_middleware(SessionMiddleware, secret_key="mysecret")
@app.get("/session")
def get_session_data(request):
# সেশন ডেটা এক্সেস করা
user = request.session.get("user", "Guest")
return {"user": user}
@app.post("/set-session")
def set_session_data(request: Request):
# সেশন ডেটা সেট করা
request.session["user"] = "John Doe"
return {"message": "Session set for John Doe"}
এখানে:
secret_key="mysecret": সেশনের কুকি এনক্রিপ্ট করার জন্য একটি গোপন কৌশল।request.session: সেশন ডেটা সংরক্ষণ এবং অ্যাক্সেস করার জন্য ব্যবহৃত হয়।
রিকোয়েস্ট উদাহরণ:
- GET
/session: সেশন থেকে ব্যবহারকারীর ডেটা ফেরত পাওয়া যাবে। - POST
/set-session: নতুন সেশন ডেটা সেট করা যাবে।
৩. GZipMiddleware
GZipMiddleware হল FastAPI এর বিল্ট-ইন একটি Middleware যা রেসপন্সের কম্প্রেশন (gzip) হ্যান্ডল করতে ব্যবহৃত হয়। এটি রেসপন্সের আকার কমাতে সাহায্য করে, বিশেষত বড় JSON বা টেক্সট ডেটার জন্য এটি অনেক কার্যকরী।
উদাহরণ: GZipMiddleware ব্যবহার করা
from fastapi import FastAPI
from starlette.middleware.gzip import GZipMiddleware
app = FastAPI()
# GZip Middleware যুক্ত করা
app.add_middleware(GZipMiddleware, minimum_size=1000) # minimum_size এর মাধ্যমে রেসপন্স কম্প্রেস করা হয় যদি তার আকার 1000 বাইটের বেশি হয়
@app.get("/")
async def get_data():
return {"message": "This response will be gzip compressed if large enough"}
এখানে:
minimum_size=1000: রেসপন্সের আকার যদি 1000 বাইটের বেশি হয়, তবে এটি স্বয়ংক্রিয়ভাবে gzip দ্বারা কম্প্রেস করা হবে।
রেসপন্স:
যদি রেসপন্স বড় হয়, এটি কম্প্রেস হয়ে ক্লায়েন্টে পাঠানো হবে।
৪. TrustedHostMiddleware
TrustedHostMiddleware হল FastAPI এর বিল্ট-ইন একটি Middleware যা অ্যাপ্লিকেশনকে শুধুমাত্র নির্দিষ্ট হোস্টনেম বা ডোমেইন থেকে রিকোয়েস্ট গ্রহণ করতে সহায়ক হয়। এটি নিরাপত্তা বৃদ্ধির জন্য ব্যবহৃত হয়।
উদাহরণ: TrustedHostMiddleware ব্যবহার করা
from fastapi import FastAPI
from starlette.middleware.trustedhost import TrustedHostMiddleware
app = FastAPI()
# TrustedHostMiddleware যুক্ত করা
app.add_middleware(TrustedHostMiddleware, allowed_hosts=["www.example.com", "*.example.com"])
@app.get("/")
async def read_root():
return {"message": "This request is from a trusted host!"}
এখানে:
allowed_hosts=["www.example.com", "*.example.com"]: শুধুমাত্র এই ডোমেইনগুলো থেকে রিকোয়েস্ট গ্রহণের অনুমতি দেয়।
রিকোয়েস্ট উদাহরণ:
যদি রিকোয়েস্ট example.com থেকে আসে, তবে এটি কাজ করবে, কিন্তু যদি অন্য কোন ডোমেইন থেকে আসে, ত্রুটি হবে।
৫. BaseHTTPMiddleware
FastAPI তে BaseHTTPMiddleware ব্যবহার করে আপনি কাস্টম Middleware তৈরি করতে পারেন যা রিকোয়েস্ট এবং রেসপন্স প্রক্রেসে নিজস্ব লজিক যোগ করতে পারে।
উদাহরণ: Custom Middleware (BaseHTTPMiddleware)
from fastapi import FastAPI
from starlette.middleware.base import BaseHTTPMiddleware
class CustomMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request, call_next):
# রিকোয়েস্ট আসার আগে কাজ
print(f"Request URL: {request.url}")
# রিকোয়েস্ট প্রসেস করা হচ্ছে
response = await call_next(request)
# রেসপন্স আসার পরে কাজ
response.headers['X-Custom-Header'] = 'Custom Header Value'
return response
app = FastAPI()
# কাস্টম Middleware যুক্ত করা
app.add_middleware(CustomMiddleware)
@app.get("/")
async def read_root():
return {"message": "Hello, FastAPI!"}
এখানে:
dispatchমেথডটি রিকোয়েস্ট আসার আগে এবং রেসপন্স তৈরি হওয়ার পরে কার্যকর হয়।call_nextহল একটি ফাংশন যা পরবর্তী রিকোয়েস্ট প্রসেসিং করে এবং রেসপন্স ফিরিয়ে আনে।
FastAPI তে বিল্ট-ইন Middleware ব্যবহারের মাধ্যমে বিভিন্ন সাধারণ কার্যকলাপ যেমন CORS হ্যান্ডলিং, সেশন ম্যানেজমেন্ট, রেসপন্স কম্প্রেশন, নিরাপত্তা নিশ্চিতকরণ, এবং কাস্টম প্রসেসিং করা যেতে পারে। এসব Middleware আপনাকে দ্রুত এবং সুরক্ষিত অ্যাপ্লিকেশন ডেভেলপ করতে সাহায্য করে এবং কোডের পুনঃব্যবহারযোগ্যতা এবং রক্ষণাবেক্ষণ সহজ করে।
FastAPI তে Middleware ব্যবহার করা হয় বিভিন্ন ধরনের টাস্ক যেমন লগিং, রিকোয়েস্ট এবং রেসপন্স মডিফিকেশন, সিকিউরিটি চেক ইত্যাদি করার জন্য। Custom Middleware তৈরি করা খুবই সহজ এবং এর মাধ্যমে আপনি FastAPI অ্যাপ্লিকেশনের কার্যক্ষমতা এবং নিরাপত্তা বাড়াতে পারেন।
এখানে, আমরা দেখব কিভাবে FastAPI-তে Custom Middleware তৈরি এবং কনফিগার করা যায়।
Middleware কী?
Middleware হল একটি ফাংশন বা ক্লাস যা HTTP রিকোয়েস্ট আসার আগে এবং HTTP রেসপন্স ফেরানোর পরে কার্যকর হয়। FastAPI তে Middleware ব্যবহারের মাধ্যমে আপনি রিকোয়েস্ট প্রসেসিংয়ের প্রক্রিয়া পরিবর্তন করতে বা অতিরিক্ত কাজ (যেমন লগিং, অথেনটিকেশন) করতে পারেন।
FastAPI তে Middleware সাধারণত দুটি পদ্ধতিতে কাজ করে:
- Before Request: রিকোয়েস্ট আসার আগে কিছু কার্যকলাপ সম্পাদন করা।
- After Response: রেসপন্স ফেরানোর আগে বা পরে কিছু কার্যকলাপ সম্পাদন করা।
Step 1: Custom Middleware তৈরি করা
Custom Middleware তৈরি করতে, FastAPI তে BaseHTTPMiddleware ক্লাস ব্যবহার করতে হয়, যা starlette.middleware.base থেকে আসে। এর মাধ্যমে আমরা dispatch মেথড ওভাররাইড করে Middleware তৈরি করতে পারি।
উদাহরণ: Simple Logging Middleware
from fastapi import FastAPI
from starlette.middleware.base import BaseHTTPMiddleware
import time
class LoggingMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request, call_next):
start_time = time.time()
response = await call_next(request)
process_time = time.time() - start_time
print(f"Request processed in {process_time} seconds")
return response
app = FastAPI()
# Custom Middleware যোগ করা
app.add_middleware(LoggingMiddleware)
@app.get("/")
def read_root():
return {"message": "Hello, World!"}
এখানে:
LoggingMiddlewareএকটি Custom Middleware যা রিকোয়েস্ট প্রোসেস করার সময় কতটা সময় লাগছে তা লগ করে।call_nextব্যবহার করে রিকোয়েস্ট প্রসেস করার পরে রেসপন্সটি ফেরত দেওয়া হয়।start_timeএবংprocess_timeব্যবহার করে মোট প্রসেসিং সময় বের করা হচ্ছে।
রিকোয়েস্ট উদাহরণ:
GET /
রেসপন্স:
{
"message": "Hello, World!"
}
লগ:
Request processed in 0.0003 seconds
Step 2: Request এবং Response Manipulation Middleware
Custom Middleware ব্যবহার করে আপনি Request এবং Response উভয়কে ম্যানিপুলেট করতে পারেন। উদাহরণস্বরূপ, আপনি রিকোয়েস্ট হেডার বা রেসপন্স কন্টেন্ট পরিবর্তন করতে পারেন।
উদাহরণ: Custom Header Add করা Middleware
from fastapi import FastAPI
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.responses import Response
class AddCustomHeaderMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request, call_next):
response: Response = await call_next(request)
response.headers["X-Custom-Header"] = "This is a custom header"
return response
app = FastAPI()
# Custom Middleware যোগ করা
app.add_middleware(AddCustomHeaderMiddleware)
@app.get("/")
def read_root():
return {"message": "Custom header added!"}
এখানে:
AddCustomHeaderMiddlewareএকটি Middleware যা রেসপন্সেX-Custom-Headerযোগ করে।call_nextরিকোয়েস্ট প্রসেস করার পর, রেসপন্সে কাস্টম হেডারটি যোগ করা হচ্ছে।
রিকোয়েস্ট উদাহরণ:
GET /
রেসপন্স:
{
"message": "Custom header added!"
}
Response Header:
X-Custom-Header: This is a custom header
Step 3: Error Handling Middleware
Middleware ব্যবহার করে আপনি Error Handlingও করতে পারেন, যেমন রিকোয়েস্ট প্রোসেস করার সময় কোনো ত্রুটি হলে তা হ্যান্ডেল করা।
উদাহরণ: Custom Error Handling Middleware
from fastapi import FastAPI
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.responses import JSONResponse
class ErrorHandlingMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request, call_next):
try:
response = await call_next(request)
return response
except Exception as e:
return JSONResponse(
status_code=500,
content={"detail": f"An error occurred: {str(e)}"}
)
app = FastAPI()
# Custom Middleware যোগ করা
app.add_middleware(ErrorHandlingMiddleware)
@app.get("/")
def read_root():
return {"message": "Hello, World!"}
@app.get("/error")
def cause_error():
raise Exception("Something went wrong!")
এখানে:
ErrorHandlingMiddlewareএকটি Custom Middleware যা যে কোনো ত্রুটি ধরবে এবং একটি কাস্টম JSON রেসপন্স ফেরত দেবে।
রিকোয়েস্ট উদাহরণ:
GET /error
রেসপন্স (ত্রুটি):
{
"detail": "An error occurred: Something went wrong!"
}
Step 4: Dependency Injection Middleware
FastAPI তে Middleware ব্যবহার করে আপনি Dependency Injection করতে পারেন। উদাহরণস্বরূপ, আপনি একটি নির্দিষ্ট ডিপেনডেন্সি ইনজেক্ট করতে পারেন যা Middleware এর মধ্যে কাজ করবে।
উদাহরণ: Dependency Injection Middleware
from fastapi import FastAPI, Depends
from starlette.middleware.base import BaseHTTPMiddleware
class DependencyInjectionMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request, call_next):
# Dependency Injection: Adding a custom value to the request state
request.state.custom_value = "Injected Value"
response = await call_next(request)
return response
app = FastAPI()
# Custom Middleware যোগ করা
app.add_middleware(DependencyInjectionMiddleware)
@app.get("/")
def read_root(request: Request):
return {"message": f"Custom value: {request.state.custom_value}"}
এখানে:
request.state.custom_valueব্যবহার করে Middleware তে ডিপেনডেন্সি ইনজেক্ট করা হয়েছে এবং তা পরে রিকোয়েস্টে ব্যবহৃত হচ্ছে।
রিকোয়েস্ট উদাহরণ:
GET /
রেসপন্স:
{
"message": "Custom value: Injected Value"
}
Step 5: Configuring Middleware Order
FastAPI তে আপনি Middleware Order কনফিগার করতে পারেন, অর্থাৎ কোন Middleware প্রথমে কার্যকর হবে এবং কোনটি পরে। Middleware এর কার্যক্রম নির্ধারণ করতে এটি গুরুত্বপূর্ণ হতে পারে।
from fastapi import FastAPI
from starlette.middleware.base import BaseHTTPMiddleware
class FirstMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request, call_next):
print("First Middleware")
response = await call_next(request)
return response
class SecondMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request, call_next):
print("Second Middleware")
response = await call_next(request)
return response
app = FastAPI()
# Middleware গুলি যোগ করা
app.add_middleware(FirstMiddleware)
app.add_middleware(SecondMiddleware)
@app.get("/")
def read_root():
return {"message": "Hello, World!"}
এখানে, FirstMiddleware প্রথমে কার্যকর হবে, তারপর SecondMiddleware।
রিকোয়েস্ট উদাহরণ:
GET /
কনসোল আউটপুট:
First Middleware
Second Middleware
FastAPI তে Custom Middleware তৈরি করা এবং কনফিগার করা খুবই সহজ। Middleware ব্যবহার করে আপনি বিভিন্ন ধরনের কাজ করতে পারেন, যেমন লগিং, রিকোয়েস্ট এবং রেসপন্স মডিফিকেশন, সিকিউরিটি চেক ইত্যাদি। Middleware ব্যবস্থাপনা ব্যবহার করে আপনি আপনার অ্যাপ্লিকেশনের কার্যক্ষমতা, নিরাপত্তা এবং মান উন্নত করতে পারেন।
Request এবং Response Lifecycle হ্যান্ডলিং হলো FastAPI-তে রিকোয়েস্ট গ্রহণ থেকে শুরু করে রেসপন্স পাঠানোর পর্যায় পর্যন্ত সবকিছু নিয়ন্ত্রণ করার প্রক্রিয়া। FastAPI তে এটি Middleware এবং Dependency Injection ব্যবহার করে সহজেই করা যায়। Middleware এবং Life Cycle হ্যান্ডলিংয়ের মাধ্যমে আপনি রিকোয়েস্ট এবং রেসপন্সে প্রি-প্রসেসিং বা পোস্ট-প্রসেসিং কার্যকর করতে পারেন।
এখানে, আমরা ফাস্টএপিআইতে রিকোয়েস্ট এবং রেসপন্স লাইফসাইকেল কিভাবে হ্যান্ডল করা যায় তা দেখব।
Step 1: Middleware সম্পর্কে
Middleware হলো ফাস্টএপিআইতে এমন একটি ফাংশন বা ক্লাস যা রিকোয়েস্ট এবং রেসপন্স এর মধ্যবর্তী পর্যায়ে কার্যকর হয়। Middleware ব্যবহার করে আপনি রিকোয়েস্ট প্রোসেসিং এবং রেসপন্স মডিফিকেশন করতে পারেন।
Custom Middleware তৈরি করা
FastAPI তে middleware তৈরি করার জন্য BaseHTTPMiddleware অথবা Middleware ক্লাস ব্যবহার করা যায়। এখানে আমরা একটি Custom Middleware তৈরি করব।
from fastapi import FastAPI
from starlette.middleware.base import BaseHTTPMiddleware
app = FastAPI()
class CustomMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request, call_next):
# Request প্রোসেসিং
print("Request received")
# রিকোয়েস্ট প্রসেস করা হচ্ছে
response = await call_next(request)
# Response প্রোসেসিং
response.headers['X-Custom-Header'] = 'Custom Value'
print("Response sent")
return response
# Middleware যুক্ত করা
app.add_middleware(CustomMiddleware)
@app.get("/")
async def read_root():
return {"message": "Hello, FastAPI!"}
এখানে:
dispatchমেথডটি রিকোয়েস্ট এবং রেসপন্সের মধ্যবর্তী প্রক্রিয়া নিয়ন্ত্রণ করে।call_next(request)ব্যবহার করে রিকোয়েস্ট পরবর্তী পর্যায়ে প্রোসেস করা হয়।X-Custom-Headerহেডারটি রেসপন্সে যুক্ত করা হয়েছে।
রিকোয়েস্ট এবং রেসপন্স লাইফসাইকেল:
- রিকোয়েস্ট আসার আগে
CustomMiddlewareকাজ করবে। - রেসপন্স পাঠানোর আগে middleware রেসপন্সে কাস্টম হেডার যুক্ত করবে।
Step 2: Request Lifecycle Handling
Request Lifecycle হ্যান্ডল করার জন্য আপনি middleware ব্যবহার করতে পারেন, যেখানে আপনি রিকোয়েস্টের বিভিন্ন বৈশিষ্ট্য যেমন হেডার, বডি ইত্যাদি প্রসেস করতে পারবেন।
Request Lifecycle Handling উদাহরণ:
from fastapi import FastAPI, Request
app = FastAPI()
@app.middleware("http")
async def log_request(request: Request, call_next):
# Request lifecycle - Pre-processing
print(f"Request path: {request.url.path}")
# Request প্রসেসিং
response = await call_next(request)
# Response lifecycle - Post-processing
print(f"Response status code: {response.status_code}")
return response
এখানে, log_request middleware রিকোয়েস্ট এবং রেসপন্সের তথ্য লগ করবে।
রিকোয়েস্ট এবং রেসপন্স লাইফসাইকেল:
- Pre-processing: রিকোয়েস্টের URL পাথ লগ করা হবে।
- Post-processing: রেসপন্সের স্ট্যাটাস কোড লগ করা হবে।
Step 3: Response Lifecycle Handling
Response Lifecycle হ্যান্ডল করার জন্য আপনি রেসপন্সে কাস্টম হেডার বা কন্টেন্ট মডিফাই করতে পারেন। FastAPI তে রেসপন্স তৈরি করার পর এটি শেষ না হওয়া পর্যন্ত আমরা রেসপন্সে কিছু পরিবর্তন করতে পারি।
Response Lifecycle Handling উদাহরণ:
from fastapi import FastAPI
from starlette.responses import JSONResponse
app = FastAPI()
@app.middleware("http")
async def add_custom_header(request, call_next):
response = await call_next(request)
# Response lifecycle - Post-processing
response.headers['X-Processed-By'] = 'FastAPI Middleware'
return response
@app.get("/")
async def read_root():
return JSONResponse(content={"message": "Hello, FastAPI!"})
এখানে, X-Processed-By হেডার রেসপন্সে যোগ করা হয়েছে। এটি middleware এর মাধ্যমে করা হয়েছে।
রিকোয়েস্ট এবং রেসপন্স লাইফসাইকেল:
- Pre-processing: রিকোয়েস্ট আসার পর কিছু ম্যানিপুলেশন করা যায়।
- Post-processing: রেসপন্স আসার পর হেডার বা কন্টেন্ট পরিবর্তন করা যায়।
Step 4: Request Validation and Error Handling
FastAPI তে Request Validation এবং Error Handling খুবই সহজ। আপনি পিডেন্টিক (Pydantic) মডেল ব্যবহার করে ইনপুট ডাটা ভ্যালিডেশন করতে পারেন এবং যদি কোনো ভুল হয়, FastAPI স্বয়ংক্রিয়ভাবে ত্রুটি রেসপন্স প্রদান করে।
Request Validation এবং Error Handling উদাহরণ:
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
@app.post("/items/")
async def create_item(item: Item):
if item.price <= 0:
raise HTTPException(status_code=400, detail="Price must be greater than 0")
return {"item_name": item.name, "item_price": item.price}
এখানে:
- Item মডেল ব্যবহার করে ইনপুট ভ্যালিডেশন করা হয়েছে।
- HTTPException ব্যবহার করে যদি price ০ বা তার কম হয়, তবে ত্রুটি রিটার্ন করা হবে।
রিকোয়েস্ট উদাহরণ (ভুল ইনপুট):
{
"name": "Laptop",
"price": -500.00
}
রেসপন্স (ত্রুটি):
{
"detail": "Price must be greater than 0"
}
Step 5: Dependency Injection with Request and Response
FastAPI তে Dependency Injection ব্যবহার করে আপনি রিকোয়েস্ট এবং রেসপন্সের প্রক্রিয়া সহজভাবে পরিচালনা করতে পারেন। এটি ডেটা শেয়ারিং বা রিকোয়েস্টের নির্দিষ্ট ডিপেনডেন্সি পরিচালনার জন্য ব্যবহৃত হয়।
Dependency Injection উদাহরণ:
from fastapi import FastAPI, Depends
app = FastAPI()
def get_token():
return "secret_token"
@app.get("/items/")
async def get_item(token: str = Depends(get_token)):
return {"token": token}
এখানে, get_token একটি ডিপেনডেন্সি ফাংশন, যা টোকেন প্রদান করে এবং এটি Depends ডেকোরেটর ব্যবহার করে রিকোয়েস্টে ইনজেক্ট করা হয়।
রিকোয়েস্ট উদাহরণ:
GET /items/
রেসপন্স:
{
"token": "secret_token"
}
FastAPI তে Request এবং Response Lifecycle Handling অত্যন্ত সহজ এবং শক্তিশালী। Middleware, Request Validation, Response Manipulation, এবং Error Handling ব্যবস্থাপনা করে আপনি রিকোয়েস্ট এবং রেসপন্সের প্রক্রিয়া সহজে নিয়ন্ত্রণ করতে পারেন। Middleware ব্যবহার করে আপনি রিকোয়েস্ট এবং রেসপন্সের মধ্যে বিভিন্ন কাজ করতে পারেন যেমন লোগিং, হেডার ম্যানিপুলেশন এবং অ্যাপ্লিকেশন স্টেট ম্যানেজমেন্ট। FastAPI তে এই সব ফিচার ব্যবহার করে কোড আরও মডুলার, পুনঃব্যবহারযোগ্য এবং পরীক্ষণযোগ্য হয়ে ওঠে।
Read more